package edu.xalead.版本四;

import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner;

import static sun.swing.MenuItemLayoutHelper.max;

public class Method {
    /*
        创建评分表
         */
    static final int[][] score = {
            { 0, 0,  0,  0,   0,10000 },//防守2子
            { 0, 0, 20,100, 500,10000 },//防守1子
            { 0,20,100,500,2500,10000 } //防守0子
    };

    /*
    创建棋盘
     */
    public char[][] createBoard(){
        char[][] board = new char[19][19];

        for (int i=0;i<board.length;i++){

            for (int j=0;j<board.length;j++){

                board[i][j] = '+';
            }
        }
        return board;
    }
    /*
    棋盘展示方法
     */
    public void showBoard(char[][] board){
        System.out.print(" ");
        for (int ia=0;ia<board.length;ia++){
            System.out.print(" "+ia);
        }
        System.out.println();
        for (int i=0;i<board.length;i++){
            System.out.print(i);
            for (int j=0;j<board.length;j++){
                System.out.print(" "+board[i][j]);
            }
            System.out.println();
        }
    }

    /*
    判断是否获胜
     */
     public boolean judgeSuccess(char[][] board,int x,int y,char color){
         //水平
         int starty = y-4 < 0 ? 0:y-4;
         int endy = y+4 > board.length-1 ? board.length-1 : y+4 ;
         int startx = x-4 < 0 ? 0:x-4;
         int endx = x+4 > board.length-1 ? board.length-1 : x+4 ;
         int num = 0; //作为计数器使用

         for (int i=starty;i<=endy;i++){
             if (board[x][i]== color){
                 num++;
             }else {num = 0;}
             if (num==5){
                 return true;
             }
         }
         //竖直

         for (int i=startx;i<=endx;i++){
             if (board[i][y]==color){
                 num++;
             }else {num = 0;}
             if (num==5){
                    return true;
             }
         }
         //左倾斜
         int j=starty;
         for (int i=startx;i<=endx;i++){
             if (board[i][j]==color){
                 num++;
             }else{num=0;}
             if (num==5){
                 return true;
             }
             if (j!=endy)j++;
         }

         //右倾斜
         j=endy;
         for (int i=startx;i<=endx;i++){
             if (board[i][j]==color){
                 num++;
             }else{num=0;}
             if (num==5){
                return true;
             }
             if (j!=0)j--;
         }
         return false;
     }
     /*
     下旗
      */
     public int playChess(char[][]board,int x,int y){


             if (canInput(board,x,y)==true)
             board[x][y] = '0'; //将白子落在这个位置
             //棋盘的展现
             showBoard(board);
            /*
            核心算法 判断五子成龙
             */
             if(judgeSuccess(board,x,y,'0')==true) {
                 System.out.println("白棋获胜");
                 return '0';
             }
        /*
        黑棋落子 黑棋用1表示
         */
             System.out.println("请输入你要落黑子的位置：");
             Boolean a = AI(board); //ai落子
             //棋盘的展现
             showBoard(board);
             if (a == true){
                 System.out.println("黑棋获胜");
                 return '1';}


         return 'e';
     }
     /*
     判断位置是否为空
      */
     public boolean canInput(char[][] board,int x,int y){
         if (board[x][y]=='+'){
             return true;
         } else return false;
     }

     /*
     评分估测
      */
    //米字型搜索
    //[—, | , / , \]四个移动方向
    static int inX[] = { 1,0,1,1 };
    static int inY[] = { 0,1,1,-1 };
    public int getScore(char[][] board,int x,int y,char color){
        //返回评分值
        int re = 0;

        //向 [—,|, /, \]四个方向搜索，对应inX，inY
        for (int i = 0; i < 4; ++i) {
            //k记录连子两侧空位的数目（非墙，非敌方落子）
            int k = 0;
            //记录连子的数目，初始值为1因为假设在当前位置落子
            int count = 1;

            //[—,|, /, \]四个方向的正负方向
            for (int j = -1; j < 2; j += 2) {
                int dx = x + j * inX[i];
                int dy = y + j * inY[i];

                //判断是否超出棋盘边界
                while (dx >= 0 && dx < board.length &&
                        dy >= 0 && dy < board.length) {
                    //假如遇到颜色相同的子，count+1，反之则退出循环，并判断此时有无空位
                    if (board[dx][dy]==color) {
                        ++count;
                    }
                    else {
                        if (board[dx][dy]== '+') ++k;
                        break;
                    }

                    dx += j * inX[i];
                    dy += j * inY[i];
                }
            }

            //假如连子大于5，使之等于5
            if (count > 5) count = 5;

            //加上该方向所得评分
            re += score[k][count];
        }

        return re;
    }
/*
智障小电脑
 */
     public boolean AI(char[][] board){
         int max =  0;
         ArrayList<Integer> X = new ArrayList<>();
         ArrayList<Integer> Y = new ArrayList<>();
        //遍历棋盘
         for (int i = 0; i < board.length; ++i) {
             for (int j = 0; j < board.length; ++j) {
                 //判断是否为空位
                 if (board[i][j] == '+') {
                     //进攻还是防守，寻找利益最大值
                     int score = max(getScore(board, i, j,'1'),getScore(board,i,j,'0'));
                     //以防有多个相同的最大值
                     if (score >= max) {
                         if (score > max) {
                             X.clear();
                             Y.clear();
                             max = score;
                         }
                         X.add(i);
                         Y.add(j);
                     }
                 }
             }
         }
         //在最大值中任取一个返回,大部分情况只有一个
         Random r = new Random(X.size());
         int rr = r.nextInt(X.size());
         int x = X.get(rr);
         int y = Y.get(rr);
         if (board[x][y]=='+'){
             board[x][y] = '1'; //将黑子落在这个位置
         }
         return judgeSuccess(board,x,y,'1');

     }

}
